package com.yzt.message.serviceimpl;

import android.app.NotificationChannel;
import android.content.Context;
import android.net.Uri;
import android.os.Build.VERSION_CODES;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.fastjson.JSONObject;
import com.yzt.zhuju.IService.message.IMessageService;
import com.yzt.zhuju.IService.message.MessageCallback;
import com.yzt.zhuju.IService.message.UnReadMessageCountChangeObserver;
import com.yzt.zhuju.IService.message.UnreadCountCallback;
import com.yzt.zhuju.event.RxBus;
import com.yzt.zhuju.event.im.RongYunMessageUnreadStatusEvent;
import com.yzt.zhuju.message.ConversationInfo;
import com.yzt.message.IMManager;
import com.yzt.message.custom.RXGiftMessageContent;
import com.yzt.message.msgdialog.MsgFloatDialogHelper;
import com.yzt.message.util.ConversationMessageManager;
import com.yzt.message.util.ConvertModelUtil;

import io.rong.imkit.IMCenter;
import io.rong.imkit.RongIM;
import io.rong.imkit.manager.UnReadMessageManager.IUnReadMessageObserver;
import io.rong.imkit.notification.NotificationUtil;
import io.rong.imkit.notification.RongNotificationManager;
import io.rong.imkit.userinfo.RongUserInfoManager;
import io.rong.imlib.IRongCallback;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.RongIMClient.ErrorCode;
import io.rong.imlib.RongIMClient.OperationCallback;
import io.rong.imlib.model.Conversation;
import io.rong.imlib.model.Message;
import io.rong.imlib.model.UserInfo;
import io.rong.message.TextMessage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhly
 * created on: 2022/7/19 20:37
 * description: IM消息service实现类
 */
@Route(path = "/message/messageService")
public class MessageServiceImpl implements IMessageService {

    private Context context;

    private int unreadCount;

    private final Map<UnReadMessageCountChangeObserver, IUnReadMessageObserver> unreadObservers = new ConcurrentHashMap<>();

    @Override
    public void init(Context context) {
        this.context = context;
    }

    @Override
    public void login() {
        IMManager.getInstance().getIMToken();
    }

    @Override
    public void logout() {
        RongIM.getInstance().logout();
    }

    @Override
    public void updateUserInfo(String userId, String userName, String avatar, String extraJsonStr) {
        UserInfo tempUserInfo = new UserInfo(userId, userName, Uri.parse(avatar));
        if (!TextUtils.isEmpty(extraJsonStr)) {
            tempUserInfo.setExtra(extraJsonStr);
        }
        RongIM.getInstance().setCurrentUserInfo(tempUserInfo);
        RongIM.getInstance().setMessageAttachedUserInfo(true);
        Log.e("wang", "setCurrentUserInfo-------" + JSONObject.toJSONString(tempUserInfo));
        updateUserInfoCache(tempUserInfo.getUserId(), tempUserInfo.getName(), tempUserInfo.getPortraitUri());
    }

    @Override
    public void setMessageContentShowStatus(boolean open, MessageCallback callback) {
        RongIMClient.getInstance().setPushContentShowStatus(open, new OperationCallback() {
            @Override
            public void onSuccess() {
                if (callback != null) {
                    callback.onSuccess();
                }
            }

            @Override
            public void onError(ErrorCode errorCode) {
                if (callback != null) {
                    callback.onError(errorCode.code, errorCode.msg);
                }
            }
        });
    }

    @Override
    public void setMessageSound(boolean open) {
//        RongConfigCenter.featureConfig().setSoundInForeground(open);
    }

    @Override
    public void setNotificationQuietHours(String startTime, int spanMinutes, MessageCallback callback) {
        RongNotificationManager.getInstance().setNotificationQuietHours(startTime, spanMinutes,
                new OperationCallback() {
                    @Override
                    public void onSuccess() {
                        if (callback != null) {
                            callback.onSuccess();
                        }
                    }

                    @Override
                    public void onError(ErrorCode errorCode) {
                        if (callback != null) {
                            callback.onError(errorCode.code, errorCode.msg);
                        }
                    }
                });
    }

    @Override
    public void removeNotificationQuietHours(MessageCallback callback) {
        RongNotificationManager.getInstance().removeNotificationQuietHours(new OperationCallback() {
            @Override
            public void onSuccess() {
                if (callback != null) {
                    callback.onSuccess();
                }
            }

            @Override
            public void onError(ErrorCode errorCode) {
                if (callback != null) {
                    callback.onError(errorCode.code, errorCode.msg);
                }
            }
        });
    }

    @RequiresApi(api = VERSION_CODES.O)
    @Override
    public NotificationChannel getMessageNotificationChannel() {
        return NotificationUtil.getInstance().getDefaultChannel(context);
    }

    @Override
    public void sendTextMessage(String targetUid, String messageText) {
        sendTextMessage(targetUid, messageText, null);
    }

    @Override
    public void sendTextMessage(String targetUid, String messageText, MessageCallback callback) {
        RongIM.getInstance().sendMessage(Conversation.ConversationType.PRIVATE, targetUid,
                TextMessage.obtain(messageText), messageText,
                null, new IRongCallback.ISendMessageCallback() {
                    @Override
                    public void onAttached(Message message) {
                    }

                    @Override
                    public void onSuccess(Message message) {
                        if (callback != null) {
                            callback.onSuccess();
                        }
                    }

                    @Override
                    public void onError(Message message, RongIMClient.ErrorCode errorCode) {
                        if (callback != null) {
                            callback.onError(errorCode.code, errorCode.msg);
                        }
                    }
                });
    }

    @Override
    public void sendGiftMessageToOne(String toUid, String messageText, String giftIcon) {
        RXGiftMessageContent rxGiftMessageContent = new RXGiftMessageContent();
        rxGiftMessageContent.setContent(messageText);
        Map<String, Object> extensions = new HashMap<>();
        extensions.put("giftIcon", giftIcon);
        //rxGiftMessageContent.setMyExtra(extensions);
        //Message message = Message.obtain(toUid, Conversation.ConversationType.PRIVATE, rxGiftMessageContent);
        // RongIM.getInstance().sendMessage(message, null, null, (IRongCallback.ISendMessageCallback) null);
    }

    @Override
    public void deleteConversationList(MessageCallback callback) {
        Conversation.ConversationType[] conversationTypes = {Conversation.ConversationType.PRIVATE,
                Conversation.ConversationType.GROUP,
                Conversation.ConversationType.DISCUSSION, Conversation.ConversationType.SYSTEM,
                Conversation.ConversationType.CUSTOMER_SERVICE, Conversation.ConversationType.CHATROOM,
                Conversation.ConversationType.PUBLIC_SERVICE, Conversation.ConversationType.APP_PUBLIC_SERVICE,
                Conversation.ConversationType.ENCRYPTED};
        RongIMClient.getInstance().getConversationList(new RongIMClient.ResultCallback<List<Conversation>>() {
            @Override
            public void onSuccess(List<Conversation> conversations) {
                if (conversations != null && conversations.size() > 0) {
                    for (Conversation c : conversations) {
                        IMCenter.getInstance().deleteMessages(c.getConversationType(), c.getTargetId(), null);
                        IMCenter.getInstance().removeConversation(c.getConversationType(), c.getTargetId(), null);
                        //由于业务需求，下次安装的消息是根据已读状态删除的，所有这里也要清空未读数量
                        IMManager.getInstance().clearMessageUnreadStatus(c);
                    }
                }

                if (callback != null) {
                    callback.onSuccess();
                }
            }

            @Override
            public void onError(RongIMClient.ErrorCode e) {
                if (callback != null) {
                    callback.onError(e.code, e.msg);
                }
            }
        }, conversationTypes);
    }

    @Override
    public void clearHistory(MessageCallback callback) {
        RongIMClient.getInstance().getConversationList(
                new RongIMClient.ResultCallback<List<Conversation>>() {
                    @Override
                    public void onSuccess(List<Conversation> conversations) {
                        if (conversations == null) {
                            return;
                        }
                        for (int index = 0; index < conversations.size(); index++) {
                            Conversation uiConversation = conversations.get(index);

                            //同时清除远端消息 小马说让去掉的 2021.02.04
                            if (uiConversation.getConversationType() == Conversation.ConversationType.PRIVATE) {
                                RongIMClient.getInstance().cleanRemoteHistoryMessages(Conversation.ConversationType.PRIVATE, uiConversation.getTargetId(), 0, new RongIMClient.OperationCallback() {
                                    @Override
                                    public void onSuccess() {

                                    }

                                    @Override
                                    public void onError(RongIMClient.ErrorCode errorCode) {

                                    }
                                });
                            }

                            RongIMClient.getInstance().getHistoryMessages(uiConversation.getConversationType(), uiConversation.getTargetId(), -1, 1000, new RongIMClient.ResultCallback<List<Message>>() {
                                @Override
                                public void onSuccess(List<Message> historyMessages) {
                                    int[] idMsg = new int[historyMessages.size()];
                                    for (int i = 0; i < historyMessages.size(); i++) {
                                        idMsg[i] = historyMessages.get(i).getMessageId();
                                    }
                                    if (idMsg.length > 0) {
                                        RongIMClient.getInstance().deleteMessages(idMsg, new RongIMClient.ResultCallback<Boolean>() {
                                            @Override
                                            public void onSuccess(Boolean bool) {
                                            }

                                            @Override
                                            public void onError(RongIMClient.ErrorCode e) {
                                            }
                                        });
                                    }
                                }

                                @Override
                                public void onError(RongIMClient.ErrorCode errorCode) {

                                }
                            });

                            RongIM.getInstance().clearMessages(uiConversation.getConversationType(), uiConversation.getTargetId(), new RongIMClient.ResultCallback<Boolean>() {
                                @Override
                                public void onSuccess(Boolean aBoolean) {

                                }

                                @Override
                                public void onError(RongIMClient.ErrorCode errorCode) {

                                }
                            });

                            RongIM.getInstance().clearMessagesUnreadStatus(uiConversation.getConversationType(), uiConversation.getTargetId(), new RongIMClient.ResultCallback<Boolean>() {
                                @Override
                                public void onSuccess(Boolean aBoolean) {
                                    try {
                                        RongIMClient.getInstance().syncConversationReadStatus(uiConversation.getConversationType(), uiConversation.getTargetId(), uiConversation.getSentTime(), new RongIMClient.OperationCallback() {
                                            @Override
                                            public void onSuccess() {
                                            }

                                            @Override
                                            public void onError(RongIMClient.ErrorCode errorCode) {
                                            }
                                        });
                                    } catch (Exception exception) {
                                        Log.e("gz-errror", "messagelistfragment::msg=>" + exception.getMessage());
                                    }
                                }

                                @Override
                                public void onError(RongIMClient.ErrorCode e) {

                                }
                            });
                        }

                        RongIMClient.getInstance().getUnreadCount(new RongIMClient.ResultCallback<Integer>() {
                            @Override
                            public void onSuccess(Integer integer) {
                                RxBus.getDefault().post(new RongYunMessageUnreadStatusEvent(integer));
                            }

                            @Override
                            public void onError(RongIMClient.ErrorCode errorCode) {

                            }
                        }, Conversation.ConversationType.PRIVATE);


                        if (callback != null) {
                            callback.onSuccess();
                        }

                    }

                    @Override
                    public void onError(RongIMClient.ErrorCode errorCode) {
                        if (callback != null) {
                            callback.onError(errorCode.code, errorCode.msg);
                        }
                    }
                }, Conversation.ConversationType.PRIVATE, Conversation.ConversationType.GROUP,
                Conversation.ConversationType.DISCUSSION, Conversation.ConversationType.SYSTEM,
                Conversation.ConversationType.CUSTOMER_SERVICE, Conversation.ConversationType.CHATROOM,
                Conversation.ConversationType.PUBLIC_SERVICE, Conversation.ConversationType.APP_PUBLIC_SERVICE,
                Conversation.ConversationType.ENCRYPTED);
    }

    @Override
    public void addUnReadCountChangeObserver(UnReadMessageCountChangeObserver observer) {
        if (observer == null) {
            return;
        }

        IUnReadMessageObserver rongUnreadObserver = count -> {
            if (unreadCount != count) {
                observer.onChange(count);
                unreadCount = count;
            }
        };

        RongIM.getInstance().addUnReadMessageCountChangedObserver(rongUnreadObserver, Conversation.ConversationType.PRIVATE, Conversation.ConversationType.GROUP);

        unreadObservers.put(observer, rongUnreadObserver);
    }

    @Override
    public void removeUnReadCountChangeObserver(UnReadMessageCountChangeObserver observer) {
        if (observer == null) {
            return;
        }

        IUnReadMessageObserver rongUnreadObserver = unreadObservers.remove(observer);
        RongIM.getInstance().removeUnReadMessageCountChangedObserver(rongUnreadObserver);
    }

    @Override
    public void getTotalUnreadMessageCount(UnreadCountCallback callback) {
        RongIMClient.getInstance().getUnreadCount(new RongIMClient.ResultCallback<Integer>() {
            @Override
            public void onSuccess(Integer integer) {
                if (callback != null) {
                    callback.onSuccess(integer);
                }
            }

            @Override
            public void onError(RongIMClient.ErrorCode errorCode) {
                if (callback != null) {
                    callback.onError(errorCode.code, errorCode.msg);
                }
            }
        }, Conversation.ConversationType.PRIVATE, Conversation.ConversationType.GROUP);
    }

    @Override
    public int getUnreadConversationCount() {
        return ConversationMessageManager.getInstance().getConversationSize();
    }

    @Override
    public ConversationInfo getFirstUnreadConversation() {
        return ConvertModelUtil.convertConversationInfo(ConversationMessageManager.getInstance().getFirstConversation());
    }

    @Override
    public void showMessageListDialog(FragmentActivity activity) {

    }

    @Override
    public void dismissMessageListDialog(boolean destroy) {
//        if (messageListDialog != null) {
//            if (destroy) {
//                messageListDialog.dismissAllowingStateLoss();
//                messageListDialog = null;
//            } else if (messageListDialog.getDialog() != null) {
//                messageListDialog.getDialog().dismiss();
//            }
//        }
    }

    @Override
    public void registerFloatMessage() {
        MsgFloatDialogHelper.getInstance().init();
    }

    @Override
    public void unregisterFloatMessage() {
        MsgFloatDialogHelper.getInstance().release();
    }

    /**
     * 更新 IMKit 显示用用户信息
     *
     * @param userId
     * @param userName
     * @param portraitUri
     */
    public static void updateUserInfoCache(String userId, String userName, Uri portraitUri) {
        UserInfo oldUserInfo = RongUserInfoManager.getInstance().getUserInfo(userId);
        if (oldUserInfo == null
                || (!oldUserInfo.getName().equals(userName)
                || oldUserInfo.getPortraitUri() == null
                || !oldUserInfo.getPortraitUri().equals(portraitUri))) {
            UserInfo userInfo = new UserInfo(userId, userName == null ? "" : userName, portraitUri);
            RongUserInfoManager.getInstance().refreshUserInfoCache(userInfo);
            Log.e("wang", "refreshUserInfoCache-------------" + JSONObject.toJSONString(userInfo));
        }
    }
}
